/*
 * Model class of MonteCarloApplication - single threaded
 */
package javaapplication6.MODEL.SINGLE;

import java.util.Random;
import javaapplication6.MODEL.AbstractMonteCarloSimulation;

/**
 * MonteCarlo single threaded version model of the application
 * @author mathieubakrim
 */
public class MonteCarloSimulation extends AbstractMonteCarloSimulation{
         
    /**
     * Simulation method
     * @param callPutFlag
     * @param s: share price of the day
     * @param x: strike price
     * @param t: Remaining time to option maturity
     * @param r: interest without risk
     * @param b: Carry rate cost of the option 
     * @param v: volatility
     * @param nSteps: number of intermediate points to calculate
     * @param nSimulations: number of way to explore
     * @return computed value of MonteCarlo, as an estimated price of the option
     */
    @Override
    public double MonteCarloStandardOption(String callPutFlag, double s, double x,
            double t, double r, double b,double v, int nSteps, int nSimulations){

        Random random = new Random();
        start = System.currentTimeMillis();        
                
        dt = t / nSteps;
        drift = (b - v * v / 2) * dt;
        vSqrt = v * Math.sqrt(dt);
        
        if("c".equals(callPutFlag)){    // It is a call
            z = 1;
        }            
        else if("p".equals(callPutFlag)){   // It is a put
            z = -1;
        }
         
        // Process MonteCarlo algorithm over n simulations
        for (i = 1; i <= nSimulations; i++){
            st = s;
            for(j = 1; j <= nSteps ; j++){
                st *= Math.exp(drift + (vSqrt * random.nextGaussian()));
            }
            sum += Math.max(z *(st-x), 0);
        }
        
        // Mean of the resultat of the n simulation
        res = Math.exp(-r * t)*(sum/nSimulations);
        
        end = System.currentTimeMillis();
        System.out.println("Temps total: " + (end - start) + "ms");
        System.out.println("Res : " + res);       
        return res;
    }
}
